package xj.graph2d.shapes;

import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import org.apache.commons.codec.binary.Base64;

import xj.graph2d.DrawShape;
import xj.graph2d.DrawShapeBase;
import xj.graph2d.RectangleShape;
import xj.graph2d.app.resources.SVGIcon;
import xj.lang.CodeWriter;
import xj.util.xml.XMLUtil;

public class SVGShape 
  extends RectangleShape 
  implements ShapeConstants {

  public SVGShape() {
    showborder = false;
    icon = null; 
  }

  public SVGShape(File file) throws IOException {
    this(file, false);
  }

  public SVGShape(File file, boolean createComp) 
    throws IOException {
    super(false, createComp);
    showborder = false;
    setSVG(file);
  }

  public SVGShape(byte[] svgBytes, boolean createComp) {
    super(false, createComp);
    showborder = false;
    setSVG(svgBytes);
  }

  @Override
  public DrawShape makeInstance() {
    return new SVGShape(svgBytes, comp != null);
  }
  
  @Override
public void copyTo(DrawShapeBase s) 
    throws CloneNotSupportedException {
    super.copyTo(s);
    if (s instanceof SVGShape) { 
      SVGShape svgShape = (SVGShape) s;
      svgShape.setSVG(this.svgBytes);
    }
  }

  @Override
  public String getName() {
    return "SVGImage";
  }

  public void setSVG(File file) throws IOException { 
    if (file != null) { 
      boolean zipped = (file.getName().endsWith(".svgz"));
      try { 
	FileInputStream in = new FileInputStream(file);
	Dimension dim = new Dimension(100, 100);
	icon = new SVGIcon(in, zipped, dim);
	svgBytes = icon.getSvgBytes();
      } catch (IOException e) {
	e.printStackTrace();
      }
      float x1 = (float) p1.getX();
      float y1 = (float) p1.getY();
      setEnds(x1, y1, x1 + 100, y1 + 100);
    }
  }

  public void setSVG(byte[] svgBytes) { 
    this.svgBytes = svgBytes;
    float x = (float) Math.min(p1.getX(), p2.getX());
    float y = (float) Math.min(p1.getY(), p2.getY());
    float w = (float) Math.abs(p1.getX() - p2.getX());
    float h = (float) Math.abs(p1.getY() - p2.getY());
    Dimension dim = new Dimension((int) w, (int) h);
    icon = new SVGIcon(svgBytes, dim);
    setEnds(x, y, x + w, y + h);
  }

  @Override
  public void draw(Graphics2D g2) {
    float x = (float) Math.min(p1.getX(), p2.getX());
    float y = (float) Math.min(p1.getY(), p2.getY());
    float w = (float) Math.abs(p1.getX() - p2.getX());
    float h = (float) Math.abs(p1.getY() - p2.getY());
    if ((int) w >= 1 && (int) h >= 1) {
      icon.setDimension(new Dimension((int) w, (int) h));      
      icon.paintIcon(null, g2, (int) x, (int) y);
    }
    if (showborder) {
      g2.draw(new Rectangle2D.Float(x, y, w, h));
    }
  }

  @Override
  protected void writeXMLElements(CodeWriter out, int mode,
				  String namespacePrefix) {
    if (out != null) {
      super.writeXMLElements(out, mode, namespacePrefix);
      String rname = getPrefixedName("SVGImage", namespacePrefix);
      out.print("<" + rname + ">");
      try { 
	byte[] ba = Base64.encodeBase64(svgBytes);
	String str = new String(ba, "US-ASCII");
	out.print(str);
      } catch (IOException e) {
	System.err.println(e.getMessage());
      }
      out.println("</" + rname + ">");
    }
  }

  @Override
  protected void processXMLElement(org.w3c.dom.Element e, String namespaceURI) {
    if (e != null) {
      String nodename = e.getLocalName();
      if ("SVGImage".equals(nodename)) {
	String val = XMLUtil.getTextChildNodeValue(e);
	if (val != null) {
	  val = val.trim();
	}
	try { 
	  byte[] ba = val.getBytes("US-ASCII");
	  setSVG(Base64.decodeBase64(ba));
	} catch (IOException ex) {
	  System.err.println(ex.getMessage());
	}
      } else {
	super.processXMLElement(e, namespaceURI);
      }
    }
  }

  protected SVGIcon icon;
  protected byte[] svgBytes;

  protected Dimension defaultDim = new Dimension(100, 100);
  
  static protected int svgCount = 1; 

}
